home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / Caml Light 0.7 / Caml Light 0.7 source / src / appli / graph.c < prev    next >
Text File  |  1995-06-10  |  21KB  |  515 lines

  1.     ClipRect(&CAMLGraph->portRect);
  2.     return Atom(0);
  3. }
  4.  
  5. value gr_draw_arc(argv, argn)    /* ML */
  6.     value * argv;
  7.     int argn;
  8. {
  9. #pragma unused(argn)
  10.     short h, v, r_x, r_y, start, arc;
  11.     Rect r;
  12.     
  13.     check_graph();
  14.     r_x = Short_val(argv[2]);
  15.     r_y = Short_val(argv[3]);
  16.     if ((r_x < 0) || (r_y < 0))
  17.         graphic_fail("draw_arc: radius must be positives");
  18.     h = Short_val(argv[0]);
  19.     v = convert_y(argv[1]);
  20.     SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
  21.     SetPort(CAMLOffScreen);
  22.     start = Short_val(argv[4]);
  23.     arc = Short_val(argv[5]) - start;
  24.     while (arc < 0)
  25.         arc += 360;
  26.     FrameArc(&r, 90 - start, -arc);
  27.     SetPort(CAMLGraph);
  28.     ClipRect(&grafpk->viewRect);
  29.     OffsetRect(&r, offset_x, offset_y);
  30.     FrameArc(&r, 90 - start, -arc);
  31.     ClipRect(&CAMLGraph->portRect);
  32.     return Atom(0);
  33. }
  34.  
  35. value gr_set_line_width(width)    /* ML */
  36.     value width;
  37. {
  38.     short size;
  39.     
  40.     check_graph();
  41.     size = Short_val(width);
  42.     if (size < 0)
  43.         graphic_fail("set_line_width: width must be positive");
  44.     SetPort(CAMLOffScreen);
  45.     PenSize(size, size);
  46.     SetPort(CAMLGraph);
  47.     PenSize(size, size);
  48.     return Atom(0);
  49. }
  50.  
  51. value gr_draw_char(ch)    /* ML */
  52.     value ch;
  53. {
  54.     Point p;
  55.     
  56.     check_graph();
  57.     Begin_offscreen
  58.       GetPen(&p);
  59.       DrawChar((char) Long_val(ch));
  60.     End_offscreen
  61.     SetPort(CAMLGraph);
  62.     ClipRect(&grafpk->viewRect);
  63.     MoveTo(p.h + offset_x, p.v + offset_y);
  64.     DrawChar((char) Long_val(ch));
  65.     ClipRect(&CAMLGraph->portRect);
  66.     return Atom(0);
  67. }
  68.  
  69. value gr_draw_string(str)    /* ML */
  70.     value str;
  71. {
  72.     mlsize_t len;
  73.     Point p;
  74.     
  75.     check_graph();
  76.     if ((len = string_length(str)) > 32767)
  77.         len = 32767;
  78.     Begin_offscreen
  79.       GetPen(&p);
  80.       DrawText(Bp_val(str), 0, (unsigned short) len);
  81.     End_offscreen
  82.     SetPort(CAMLGraph);
  83.     ClipRect(&grafpk->viewRect);
  84.     MoveTo(p.h + offset_x, p.v + offset_y);
  85.     DrawText(Bp_val(str), 0, (short) len);
  86.     ClipRect(&CAMLGraph->portRect);
  87.     return Atom(0);
  88. }
  89.  
  90. value gr_set_font(str)    /* ML */
  91.     value str;
  92. {
  93.     Str255 name;
  94.     short i, len, fontnum;
  95.     
  96.     check_graph();
  97.     len = string_length(str);
  98.     for(i = 0; (i < len) && (i < 255); i++)
  99.         name[i + 1] = Byte(str, i);
  100.     name[0] = i;
  101.     GetFNum(name,&fontnum);
  102.     SetPort(CAMLOffScreen);
  103.     TextFont(fontnum);
  104.     SetPort(CAMLGraph);
  105.     TextFont(fontnum);
  106.     return Atom(0);
  107. }
  108.  
  109. value gr_set_text_size(size)    /* ML */
  110.     value size;
  111. {
  112.     short s;
  113.     
  114.     check_graph();
  115.     SetPort(CAMLOffScreen);
  116.     s = Short_val(size);
  117.     if (s < 0)
  118.         graphic_fail("set_text_size: size must be positive");
  119.     TextSize(s);
  120.     SetPort(CAMLGraph);
  121.     TextSize(s);
  122.     return Atom(0);
  123. }
  124.  
  125. value gr_text_size(str)    /* ML */
  126.     value str;
  127. {
  128.     value res;
  129.     FontInfo info;
  130.     
  131.     check_graph();
  132.     SetPort(CAMLOffScreen);
  133.     GetFontInfo(&info);
  134.     res = alloc_tuple(2);
  135.     Field(res, 0) = Val_long(TextWidth(Bp_val(str), 0, string_length(str)));
  136.     Field(res, 1) = Val_long(info.ascent + info.descent);
  137.     return res;
  138. }
  139.  
  140. value gr_fill_rect(x, y, wdth, hght)    /* ML */
  141.     value x, y, wdth, hght;
  142. {
  143.     short h, v, width, height;
  144.     Rect r;
  145.     
  146.     check_graph();
  147.     width = Short_val(wdth);
  148.     height = Short_val(hght);
  149.     if ((width < 0) || (height < 0))
  150.         graphic_fail("fill_rect: width and height must be positive");
  151.     h = Short_val(x);
  152.     v = convert_y(y) + 1;
  153.     SetRect(&r, h, v - height, h + width, v);
  154.     SetPort(CAMLOffScreen);
  155.     PaintRect(&r);
  156.     SetPort(CAMLGraph);
  157.     ClipRect(&grafpk->viewRect);
  158.     OffsetRect(&r, offset_x, offset_y);
  159.     PaintRect(&r);
  160.     ClipRect(&CAMLGraph->portRect);
  161.     return Atom(0);
  162. }
  163.  
  164. value gr_fill_arc(argv, argn)    /* ML */
  165.     value * argv;
  166.     int argn;
  167. {
  168. #pragma unused(argn)
  169.     short h, v, r_x, r_y, start, arc;
  170.     Rect r;
  171.     
  172.     check_graph();
  173.     r_x = Short_val(argv[2]);
  174.     r_y = Short_val(argv[3]);
  175.     if ((r_x < 0) || (r_y < 0))
  176.         graphic_fail("draw_arc: radius must be positives");
  177.     h = Short_val(argv[0]);
  178.     v = convert_y(argv[1]);
  179.     SetRect(&r, h - r_x, v - r_y, h + r_x + 1, v + r_y + 1);
  180.     start = Short_val(argv[4]);
  181.     arc = Short_val(argv[5]) - start;
  182.     while (arc < 0)
  183.         arc += 360;
  184.     SetPort(CAMLOffScreen);
  185.     PaintArc(&r, 90 - start, -arc);
  186.     SetPort(CAMLGraph);
  187.     ClipRect(&grafpk->viewRect);
  188.     OffsetRect(&r, offset_x, offset_y);
  189.     PaintArc(&r, 90 - start, -arc);
  190.     ClipRect(&CAMLGraph->portRect);
  191.     return Atom(0);
  192. }
  193.  
  194. value gr_fill_poly(vect)    /* ML */
  195.     value vect;
  196. {
  197.     int n_points, i;
  198.     PolyHandle poly;
  199.     
  200.     check_graph();
  201.     n_points = Wosize_val(vect);
  202.     if (n_points < 3)
  203.         graphic_fail("fill_poly: not enough points");
  204.     SetPort(CAMLOffScreen);
  205.     poly = OpenPoly();
  206.     MoveTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
  207.     for(i = 1; i < n_points; i++)
  208.         LineTo(Short_val(Field(Field(vect, i), 0)), convert_y(Field(Field(vect, i), 1)));
  209.     LineTo(Short_val(Field(Field(vect, 0), 0)), convert_y(Field(Field(vect, 0), 1)));
  210.     ClosePoly();
  211.     PaintPoly(poly);
  212.     SetPort(CAMLGraph);
  213.     ClipRect(&grafpk->viewRect);
  214.     OffsetPoly(poly, offset_x, offset_y);
  215.     PaintPoly(poly);
  216.     ClipRect(&CAMLGraph->portRect);
  217.     KillPoly(poly);
  218.     return Atom(0);
  219. }
  220.  
  221. struct image {
  222.   value w;
  223.   value h;
  224.   value data;
  225.   value mask;
  226. };
  227.  
  228. #define Width(i) (((struct image *) i)->w)
  229. #define Height(i) (((struct image *) i)->h)
  230. #define Data(i) (((struct image *) i)->data)
  231. #define Mask(i) (((struct image *) i)->mask)
  232.  
  233. static value new_bits(width, height, depth)
  234.     int width, height;
  235. {
  236.   int rowbytes, nbytes, nwords;
  237.   value res;
  238.  
  239.   rowbytes = (depth * width + 31) / 32 * 4;
  240.   nbytes = rowbytes * height;
  241.   nwords = (nbytes + 3) / 4;
  242.   if (nwords == 0) return Atom (Abstract_tag);
  243.   if (nwords <= Max_young_wosize) {
  244.     res = alloc(nwords, Abstract_tag);
  245.   }else{
  246.     res = alloc_shr(nwords, Abstract_tag);
  247.   }
  248.   return res;
  249. }
  250.  
  251. static BitMap **image_to_bitmap (image, w, h, is_mask)
  252.     value image;
  253. {
  254.   if (color_qd && !is_mask){
  255.     GDHandle old_device;
  256.     PixMapHandle result;
  257.     
  258.     old_device = GetGDevice ();
  259.     SetGDevice (CAMLGDevice);
  260.     result = NewPixMap ();
  261.     DisposHandle ((Handle) (*result)->pmTable);
  262.     (*result)->pmTable = (*((CGrafPtr) CAMLOffScreen)->portPixMap)->pmTable;
  263.     (*result)->baseAddr = (Ptr) image;
  264.     (*result)->rowBytes = (max_depth * w + 31) / 32 * 4 + 0x8000;
  265.     SetRect (&(*result)->bounds, 0, 0, w, h);
  266.     SetGDevice (old_device);
  267.     return (BitMap **) result;
  268.   }else{
  269.     BitMap **result = (BitMap **) NewHandle (sizeof (BitMap));
  270.  
  271.     (*result)->baseAddr = (Ptr) image;
  272.     (*result)->rowBytes = (w + 31) / 32 * 4;
  273.     SetRect(&(*result)->bounds, 0, 0, w, h);
  274.     return result;
  275.   }
  276. }
  277.  
  278. value gr_make_image (value mat)    /* ML */
  279. {
  280.   int height, width, i, j;
  281.   int has_transp;
  282.   GrafPtr old_port;
  283.   value res;
  284.   Push_roots(roots, 3)
  285. #define bdata (roots[0])
  286. #define bmask (roots[1])
  287. #define matrix (roots[2])
  288.   
  289.   check_graph ();
  290.   matrix = mat;
  291.   GetPort (&old_port);
  292.   height = Wosize_val(matrix);
  293.   if (height == 0) {
  294.     width = 0;
  295.   } else {
  296.     width = Wosize_val(Field(matrix, 0));
  297.     for (i = 1; i < height; i++) {
  298.       if (width != Wosize_val(Field(matrix, i)))
  299.     graphic_fail("make_image: non-rectangular matrix");
  300.     }
  301.   }
  302.   bdata = new_bits (width, height, max_depth);
  303.   has_transp = 0;
  304.   if (color_qd){
  305.     CGrafPort port;
  306.     RGBColor qd_col;
  307.     long col;
  308.     
  309.     OpenCPort (&port);
  310.     DisposHandle ((Handle) port.portPixMap);
  311.     port.portPixMap = (PixMapHandle) image_to_bitmap (bdata, width, height, 0);
  312.     port.portRect = (*port.portPixMap)->bounds;
  313.     for (i = 0; i< height; i++){
  314.       for (j = 0; j < width; j++){
  315.         col = Long_val (Field (Field (matrix, i), j));
  316.     if (col == -1){
  317.       has_transp = 1;
  318.     }else{
  319.       qd_col.red = (col >> 16) * 256;
  320.       qd_col.green = ((col >> 8) & 0xff) * 256;
  321.       qd_col.blue = (col & 0xff) * 256;
  322.           SetCPixel (j, i, &qd_col);
  323.     }
  324.       }
  325.     }
  326.     SetPort (old_port);
  327.     CloseCPort (&port);
  328.   }else{
  329.     GrafPort port;
  330.     BitMap **h;
  331.     
  332.     OpenPort (&port);
  333.     h = image_to_bitmap (bdata, width, height, 0);
  334.     port.portBits = **h;
  335.     DisposHandle ((Handle) h);
  336.     port.portRect = port.portBits.bounds;
  337.     EraseRect (&port.portBits.bounds);
  338.     for (i = 0; i< height; i++){
  339.       for (j = 0; j < width; j++){
  340.         switch (Long_val (Field (Field (matrix, i), j))){
  341.     case -1: has_transp = 1; break;
  342.     case 0xFFFFFF: break;
  343.     default: MoveTo (j, i); Line (0, 0); break;
  344.     }
  345.       }
  346.     }
  347.     SetPort (old_port);
  348.     ClosePort (&port);
  349.   }
  350.   if (has_transp) {
  351.     GrafPort port;
  352.     BitMap **h;
  353.  
  354.     bmask = new_bits (width, height, 1);
  355.     OpenPort (&port);
  356.     h = image_to_bitmap (bmask, width, height, 1);
  357.     port.portBits = **h;
  358.     DisposHandle ((Handle) h);
  359.     port.portRect = port.portBits.bounds;
  360.     EraseRect (&port.portBits.bounds);
  361.     for (i = 0; i< height; i++){
  362.       for (j = 0; j < width; j++){
  363.         if (Long_val (Field (Field (matrix, i), j)) != -1){
  364.       MoveTo (j, i); Line (0, 0);
  365.     }
  366.       }
  367.     }
  368.     SetPort (old_port);
  369.     ClosePort (&port);
  370.   }else{
  371.     bmask = Val_long (0);
  372.   }
  373.   res = alloc_tuple (4);
  374.   Width (res) = Val_int (width);
  375.   Height (res) = Val_int (height);
  376.   Data (res) = bdata;
  377.   Mask (res) = bmask;
  378.   Pop_roots ();
  379.   return res;
  380. #undef matrix
  381. #undef bdata
  382. #undef bmask
  383. }
  384.  
  385. static value alloc_int_vect(size)
  386.     mlsize_t size;
  387. {
  388.     value res;
  389.     mlsize_t i;
  390.     
  391.     if (size == 0) return Atom(0);
  392.     if (size <= Max_young_wosize) {
  393.         res = alloc(size, 0);
  394.     } else {
  395.         res = alloc_shr(size, 0);
  396.     }
  397.     for (i = 0; i < size; i++) {
  398.         Field(res, i) = Val_long(0);
  399.     }
  400.     return res;
  401. }
  402.     
  403. value gr_dump_image(value image)    /* ML */
  404. {
  405.   int height, width, i, j;
  406.   GrafPtr old_port;
  407.   Push_roots(roots, 2);
  408. #define matrix (roots[0])
  409. #define im (roots [1])
  410.  
  411.   check_graph ();
  412.   im = image;
  413.   GetPort (&old_port);
  414.   height = Int_val (Height (im));
  415.   width = Int_val (Width (im));
  416.   matrix = alloc_int_vect (height);
  417.   for (i = 0; i < height; i++) {
  418.     modify (&Field (matrix, i), alloc_int_vect (width));
  419.   }
  420.  
  421.   if (color_qd){
  422.     CGrafPort port;
  423.     RGBColor qd_col;
  424.      
  425.     OpenCPort (&port);
  426.     DisposHandle ((Handle) port.portPixMap);
  427.     port.portPixMap
  428.       = (PixMapHandle) image_to_bitmap (Data (im), width, height, 0);
  429.     port.portRect = (*port.portPixMap)->bounds;
  430.     for (i = 0; i< height; i++){
  431.       for (j = 0; j < width; j++){
  432.         GetCPixel (j, i, &qd_col);
  433.     Field (Field (matrix, i), j) = Val_long ((qd_col.red / 256 << 16)
  434.                                              + (qd_col.green / 256 << 8)
  435.                          + qd_col.blue / 256);
  436.       }
  437.     }
  438.     SetPort (old_port);
  439.     CloseCPort (&port);
  440.   }else{
  441.     GrafPort port;
  442.     BitMap **h;
  443.     
  444.     OpenPort (&port);
  445.     h = image_to_bitmap (Data (im), width, height, 0);
  446.     port.portBits = **h;
  447.     DisposHandle ((Handle) h);
  448.     port.portRect = port.portBits.bounds;
  449.     for (i = 0; i< height; i++){
  450.       for (j = 0; j < width; j++){
  451.         Field (Field (matrix, i), j)
  452.       = Val_long (GetPixel (j, i) ? 0 : 0xFFFFFF);
  453.       }
  454.     }
  455.     SetPort (old_port);
  456.     ClosePort (&port);
  457.   }
  458.  
  459.   if (Mask(im) != Val_long(0)) {
  460.     GrafPort port;
  461.     BitMap **h;
  462.     
  463.     OpenPort (&port);
  464.     h = image_to_bitmap (Mask (im), width, height, 1);
  465.     port.portBits = **h;
  466.     DisposHandle ((Handle) h);
  467.     port.portRect = port.portBits.bounds;
  468.     for (i = 0; i< height; i++){
  469.       for (j = 0; j < width; j++){
  470.         if (! GetPixel (j, i)) Field (Field (matrix, i), j) = -1;
  471.       }
  472.     }
  473.     SetPort (old_port);
  474.     ClosePort (&port);
  475.   }
  476.   Pop_roots();
  477.   return matrix;
  478. #undef matrix
  479. #undef im
  480. }
  481.  
  482. value gr_draw_image(image, x, y)    /* ML */
  483.     value image, x, y;
  484. {
  485.   short rx, ry;
  486.   int w, h;
  487.   BitMap **src_bitmap, **mask_bitmap;
  488.   Rect dst_rect, src_rect;
  489.   
  490.   check_graph();
  491.   w = Int_val (Width (image));
  492.   h = Int_val (Height (image));
  493.   rx = Long_val(x);
  494.   ry = convert_y(y) - h + 1;
  495.   SetRect (&dst_rect, rx, ry, rx + w, ry + h);
  496.   SetRect (&src_rect, 0, 0, w, h);
  497.   Begin_offscreen
  498.     if (Mask (image) != Val_long(0)) {
  499.       src_bitmap = image_to_bitmap (Data(image), w, h, 0);
  500.       mask_bitmap = image_to_bitmap (Mask(image), w, h, 1);
  501.       copy_mask (*src_bitmap, *mask_bitmap, &CAMLOffScreen->portBits,
  502.              &src_rect, &src_rect, &dst_rect);
  503.       DisposHandle ((Handle) src_bitmap);
  504.       DisposHandle ((Handle) mask_bitmap);
  505.     }else{
  506.       src_bitmap = image_to_bitmap (Data(image), w, h, 0);
  507.       copy_bits (*src_bitmap, &CAMLOffScreen->portBits,
  508.                  &src_rect, &dst_rect, srcCopy, nil);
  509.       DisposHandle ((Handle) src_bitmap);
  510.     }
  511.   End_offscreen
  512.   OffsetRect(&dst_rect, offset_x, offset_y);
  513.   SectRect(&dst_rect, &grafpk->viewRect, &dst_rect);
  514.   src_rect = dst_rect;
  515.   OffsetRect(&src_rect, -offset_x, -offset